# Концепция
Простой TCP-сервер (программное обеспечение) для Linux, действующий в качестве посредника (брокера) между клиентами,
которые размещают команды ("клиентами-постерами"), и клиентами, которые запрашивают размещённые команды
("клиентами-подписчиками"). Команды хранятся на сервере в специальных файлах - "топиках".

По получении сообщения (пакета TCP), формат и содержание которого соответствуют требованиям сервера, он:
- по указанию клиента-постера меняет размещённую в топике команду, либо
- по запросу клиента-подписчика направляет ему размещённую в топике команду.

Топики хранятся в директории `/server0451/.topics`. Изначально их не существует, они создаются сервером при первом
обращении клиента к топику с соответствующим именем (номером). Топиков может быть до 100 штук, пронумерованных
от 1 до 100, и разные клиенты-подписчики (их группы) могут обращаться к разным топикам, благодаря чему может
осуществляться раздельное управление устройствами (их группами).

Клиентами могут быть любые устройства, способные к коммуникации по TCP/IP, но роль клиентов-подписчиков предполагается
в первую очередь для устройств IoT, например, модулей ESP8266 или ESP32 с прошивкой 
"[Релешка](https://github.com/ErlingSigurdson/Billy_the_Relay)
[Билли](https://gitflic.ru/project/efimov-d-v/billy_the_relay)". Со смартфона удобно отдавать серверу команды с помощью
приложения для отправки пакетов TCP, например, [Serial Wi-Fi terminal](https://www.kai-morich.de/android)
от разработчика Kai Morich.

Сервер может работать как в локальной, так и в глобальной сети - лишь бы был индивидуальный IP-адрес, по которому
к нему можно обратиться.

### Протокол
Сервер принимает от клиентов простые последовательности байт, то есть сырые (raw) данные.
Направляемые серверу сообщения должны следовать формату:

```
<пароль>:topic_<X>:<директива>
```
где:
- пароль - заданный для сервера пароль;
- X - номер топика, от 1 до 100;
- директива - одна из валидных директив.
Двоеточия означают буквально двоеточия.

Перечень директив, на которые реагирует сервер, закрытый:
- `AT+SETLOAD=ON` - размещает в топике строку "AT+SETLOAD=ON" (команда включения нагрузки).
- `AT+SETLOAD=OFF` - размещает в топике строку "AT+SETLOAD=OFF" (команда выключения нагрузки).
- `AT+SETLOAD=TOGGLE` - размещает в топике строку, соответствующую команде, противоположной ныне размещённой.
- `AT+SERVETOPIC` - направляет клиенту текущее содержимое топика.

### Команда запуска
Общий вид команды запуска сервера следующий:
```
sudo execute_server0451 -p <номер_порта> -P <пароль> [-o][-h][-v][-V]
```
Опции `-p` и `-P` являются обязательными. Необязательные опции модифицируют поведение программы:
- `-o` - флаг запуска сервера в режиме одиночного тестового прогона.
- `-v` - включает вывод в `stdout` информации о действиях сервера, о принятых и переданных сообщениях.
- `-V` - аналогично предыдущему, но дополнительно выводит информацию о включении опций сокетов и о проблемах
при закрытии сокетов.
- `-h` - выводит в `stdout` англоязычную страницу с подсказками по использованию программы и прекращает
выполнение программы.


# Инструкция
### Компиляция
Зайдите в директорию `/server0451/src` и запустите команду `make`. Исполняемый бинарный файл программы появится
в директории `/server0451/.bin`.

### Настройка
В настроечном файле `/server0451/.config/config_server0451`:
- задайте номер порта, который будет использоваться сервером. Значение по умолчанию: 451.
- задайте пароль, с которого должны будут начинаться все направляемые серверу сообщения. Пароль по умолчанию - "admin".
Пароль может состоять из цифр и из строчных и заглавных английских букв. Длина пароля должна составлять от 5 до 40
символов.
- задайте режим работы сервера - "loop" для постоянной работы или "oneshot" для одиночного тестового прогона.
Значение по умолчанию: "loop".
- задайте максимальный размер файла с логами сервера (в байтах).
- задайте статус опции автоматического перезапуска сервера при избытке соединений в статусе "CLOSE-WAIT"
("on" или "off"). Значение по умолчанию: "off".

### Быстрый старт
Запустите исполняемый скрипт оболочки `/server0451/run_server0451.sh`.

### Логи
Логи сервера хранятся в директории `/server0451/.log/log_server0451`. Если сервер запускается в режиме постоянной
работы, то одновременно будет запущен скрипт оболочки `log_flush_server0451.sh`, который будет обнулять содержимое
файла с логами по достижении им заданного предельного размера.

Для чтения логов удобно использовать следующие команды:
```
grep -in "start" log_server0451
grep -in "accept" log_server0451
grep -in "timeout" log_server0451
```

### Остановка сервера
Для остановки сервера запустите скрипт оболочки `kill_server0451.sh`.

### Отслеживание зависших соединений
Вообще таких ситуаций быть не должно (и тесты актуальной версии сервера показывают, что они не возникают),
но теоретически ошибка при закрытии клиентом коммуникации может приводить к "зависанию" соединения в статусе
"CLOSE-WAIT". Поэтому если сервер запускается в режиме постоянной работы, то, при включённой в настроечном файле
опции "TRACE", одновременно будет запущен скрипт оболочки, который перезапустит сервер при обнаружении таких
зависших соединений.

### server0451 как служба systemd
Если вы захотите поэкспериментировать и запустить сервер как службу systemd, unit-файл может выглядеть примерно
следующим образом:
```
[Unit]
Description=A simple TCP IoT server.
After=default.target

[Service]
Type=simple
ExecStart=sudo %h/server0451/.bin/exec_bin_server0451 -p 451 -P admin -V
StandardOutput=file:%h/server0451/.log/log_server0451
Restart=always

[Install]
WantedBy=default.target
```

# Справедливые вопросы
### Почему "0451"?
[Отсылка](https://deusex.fandom.com/wiki/0451) к серии видеоигр "Deus Ex".

### Почему не MQTT?
Не так интересно. Используя такую простую программу как server0451, можно в деталях пощупать, что происходит
на сервере и как программа взаимодействует с файлами.

### Будет ли программа работать после закрытия терминала?
Циклический запуск программы осуществляется скриптом `run_server0451.sh` с помощью утилиты `nohup`, дабы программа
гарантированно продолжала работать после закрытия вашей сессии работы с оболочкой операционной системы.

### Что с безопасностью?
Это не то программное обеспечение, которое предназначено для выполнения ответственных задач, но наличие заданного
серверу пароля, который сервер будет искать в каждом сообщении и не найдя который он не будет принимать команды,
по крайней мере, задаёт индивидуальный синтаксис обращения к серверу. Шифрование отсутствует.

### Совместимо ли это ПО с другими UNIX-подобными операционными системами?
Исходный код на языке Си и скрипты оболочки написаны с соблюдением стандарта POSIX, поэтому совместимость
предполагается. Но это не точно. 


# Note for English speakers
Please note that help page is written in English. Run binary executable file with an `-h` argument to read it
or refer to `help_page.h`.
